<?php

namespace App\Http\Controllers\Api;

use App\Models\Constant\Fields;
use App\Models\Error;
use App\Models\SystemManagement\Employee;
use App\Models\Api\ScanLogin;
use App\Models\SystemManagement\User;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use SimpleSoftwareIO\QrCode\Facades\QrCode;
use Illuminate\Support\Facades\Redis;
use App\Http\Controllers\Auth\JwtToken;
use App\Models\Api\Files;
use Validator;

/**
 * @group 登录管理
 *
 * 采用 restful api
 *
 * Body Parameters 表示请求的所需要的参数
 *
 * Query Parameters 表示返回参数的名称
 */
class LoginController extends Controller
{
    public $user = null;
    /**
     * 登录
     * @param Request $request
     * @bodyParam username string required 登录名:(admin)
     * @bodyParam password string required 登陆密码:(admin)
     * @return \Illuminate\Http\JsonResponse
     * @response 200 {"data": {
     *   "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC96aGlodWlodWFud2VpLmNvbVwvbG9naW4iLCJpYXQiOjE1NzM3MTY4NTMsImV4cCI6MTU3MzcyMDQ1MywibmJmIjoxNTczNzE2ODUzLCJqdGkiOiJaUlc4VDdEdVowSXJpTlhxIiwic3ViIjo2LCJwcnYiOiI0NGU3MGU0Nzg2YzU2ZGU4OThlMDdkOGM2YTcxZTZkYTdkZjdhNmQwIn0.iaA-UR4qrghBGy3uMhDkyRjgir29Fi2UcEpeEWkQicI",
     *   "token_type": "Bearer",
     *   "expires_in": 3600},"code": 200,"msg": "success"}
     * @response 400 {"code":400,"msg":"param error","data":"验证码不正确/请输入用户名或密码"}
     * @response 404 {"code":404,"msg":"not found","data":"用户名或密码错误"}
     */
    public function login(Request $request)
    {

        $check = $this->checkPost($request);
        if ($check) {
            return $check;
        }
        $login = [
            'username' => $request->username,
            'password' => $request->password
        ];
        $token = $this->guard()->attempt($login);
        if ($token) {
            Session(['login.username' => $request->username,'login.user_id'=>$this->user->id]);
            return $this->respondWithToken($token);
        }
    }

    public function appLogin(Request $request)
    {
        $login = [
            'username' => $request->username,
            'password' => $request->password
        ];
//        if(User::where($login)->count() <= 0)
//            return response()->json('no user',401);
//        $user = User::where($login)->first();
//        $token = JwtToken::genUserToken($user->id);
//        $data = encodeMsg(array(
//            'access_token'=>$token,
//            'token_type'=>'jwt',
//            'expires_in'=>time() + JwtToken::getTokenExpireTime('login')
//        ),200);
        $token = $this->guard()->attempt($login);
        dd($token);
        //return response()->json($data);

    }

    /**
     * 扫码登录->平板获取二维码生成的唯一id号
     *
     * @bodyParam uid string optional 如果获取了id号,之后每秒刷新一下,如果手机扫码登录了这边就会返回200和token 否则403 手机还未扫码成功 404登录失效 重新刷新二维码
     *
     */
    public function scanLoginUid(Request $request)
    {
        $validator = Validator::make($request->all(),genValidate());
        if($validator->fails()){
            return response()->json(encodeMsg($validator->errors()->messages(),400),400);
        }
        if(!$request->get('uid')) {
            $uid = uniqid();
            try {
                ScanLogin::create(['uid' => $uid]);
            } catch (\Exception $e) {
                return response()->json($e->getMessage(), 500);
            }
            $qrcode = "data:image/png;base64,".base64_encode(QrCode::format('png')->size(400)->generate($uid));//网址为手机端授权登录页面地址

            return response(['qrcode'=>$qrcode,'uid'=>$uid], 201);
        }else{

            $time = time() - 60*1;
            $date=date("Y-m-d H:i:s",$time);
            $auth = ScanLogin::where(['uid'=>$request->get('uid'),'is_used'=>true])->where('created_at','<',$date)->count();
            if($auth > 0){
                return response()->json('登录失效',404);
            }

            $auth = ScanLogin::where(['uid'=>$request->get('uid'),'is_used'=>false])->where('created_at','>',$date)->count();
            if($auth > 0){
                return response()->json('手机还未扫码',403);
            }
            $auth = ScanLogin::where(['uid'=>$request->get('uid'),'is_used'=>true])->where('created_at','>',$date)->count();
            if($auth > 0){
                $auth =  ScanLogin::with('user')->where(['uid'=>$request->get('uid'),'is_used'=>true])->where('created_at','>',$date)->first()->toArray();
                if(is_null($auth['user']))
                    return response()->json('手机扫码识别 请重新扫码',406);
                $token = JwtToken::genUserToken($auth['user']['id']);
                $data = encodeMsg(array(
                    'access_token'=>$token,
                    'token_type'=>'jwt',
                    'expires_in'=>time() + JwtToken::getTokenExpireTime('login')
                ),200);
                return response()->json($data);
            }
            else{
                return response()->json('二维码不存在',405);
            }
        }
    }

    /**
     * 扫码登录->手机端扫码登录提交uid,让平板得以登录
     *
     * 报错信息
     * 402 二维码无效 请刷新
     *
     *
     * @bodyParam uid string required 手机扫码后提交上来的uid
     *
     *
     */
    public function scanLogin(Request $request)
    {
        $validator = Validator::make($request->all(),genValidate());
        if($validator->fails()){
            return response()->json(encodeMsg($validator->errors()->messages(),400),400);
        }
        $uid = $request->get('uid');
        //检查过期时间 检查是否已经被使用了
        $time = time() - 60*1;
        $date=date("Y-m-d H:i:s",$time);
        $auth = ScanLogin::where(['uid'=>$uid,'is_used'=>false])->where('created_at','>',$date)->count();
        if($auth < 1){
            return response()->json('二维码失效 请刷新',402);
        }
        ScanLogin::where(['uid'=>$uid])->update(['employee'=>$request->user_id,'is_used'=>true]);
        return response('ok');
    }

    /**
     * 登录
     * @param Request $request
     * @bodyParam username string required 登录名:(admin)
     * @bodyParam password string required 登陆密码:(admin)
     * @return \Illuminate\Http\JsonResponse
     * @response 200 {"data": {
     *   "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC96aGlodWlodWFud2VpLmNvbVwvbG9naW4iLCJpYXQiOjE1NzM3MTY4NTMsImV4cCI6MTU3MzcyMDQ1MywibmJmIjoxNTczNzE2ODUzLCJqdGkiOiJaUlc4VDdEdVowSXJpTlhxIiwic3ViIjo2LCJwcnYiOiI0NGU3MGU0Nzg2YzU2ZGU4OThlMDdkOGM2YTcxZTZkYTdkZjdhNmQwIn0.iaA-UR4qrghBGy3uMhDkyRjgir29Fi2UcEpeEWkQicI",
     *   "token_type": "Bearer",
     *   "expires_in": 3600},"code": 200,"msg": "success"}
     * @response 400 {"code":400,"msg":"param error","data":"验证码不正确/请输入用户名或密码"}
     * @response 404 {"code":404,"msg":"not found","data":"用户名或密码错误"}
     */
    public function jwtLogin(Request $request)
    {
        $login = [
            'username' => $request->username,
            'password' => $request->password
        ];
        $token = $this->guard()->attempt($login);
        if(!$token){
            return response()->json('no user',401);
        }
        $user = User::where('username',$login['username'])->first();
        $token = JwtToken::genUserToken($user->id);
        $data = encodeMsg(array(
            'access_token'=>$token,
            'token_type'=>'jwt',
            'expires_in'=>time() + JwtToken::getTokenExpireTime('login')
        ),200);
        return response()->json($data);
    }

    /**
     * 登录用户信息
     * @return \Illuminate\Http\JsonResponse
     *
     * @queryParam username 登录名
     * @queryParam password 登录密码
     * @queryParam employee_id 员工id 外键员工表
     * @queryParam status 账号状态 1:正常 2:禁止登陆
     * @queryParam picture int required 头像id
     * @queryParam condition string required 个人签名;状态
     * @queryParam start_time 有效期-开始时间
     * @queryParam end_time 有效期-结束时间
     * @queryParam last_login_time 最后登录时间
     * @queryParam last_ip 最后登录IP
     * @queryParam file->local_url string 头像url地址
     *
     * @queryParam uerInfo 员工信息
     * @queryParam id 员工id
     * @queryParam name 员工姓名
     * @queryParam id_type 证件类型 1居民身份证 2出生证 3护照
     * @queryParam id_no 证件号码
     * @queryParam id_start_time 证件生效日期
     * @queryParam id_end_time 证件失效日期
     * @queryParam birthday 出生日期
     * @queryParam phone 电话号码
     * @queryParam email 邮箱
     * @queryParam education 学历
     * @queryParam college 毕业院校
     * @queryParam age 年龄
     * @queryParam address 住址
     * @queryParam nation 民族
     * @queryParam bank_name 开户行
     * @queryParam account 银行账号
     * @queryParam organization_id 组织id
     * @queryParam organization->name 组织名称
     * @queryParam department_id 部门id
     * @queryParam department->name 部门名称
     * @queryParam post_id 岗位id
     * @queryParam post->name 岗位名称
     * @queryParam skill_id 职级id
     * @queryParam skill->name 职级名称
     * @queryParam emergency_contact 紧急联系人
     * @queryParam emergency_phone 紧急联系人电话
     * @queryParam emergency_relation 紧急联系人关系
     * @queryParam file->local_url string 头像url地址
     *
     */
    public function userInfo()
    {
        $user = $this->guard()->user();
        $user['file'] = Files::find($user->picture);
        $user['uerInfo'] = Employee::getOne($user->employee_id);
        return response()->json(encodeMsg($user, 200));
    }

    /**
     * 退出
     * @return \Illuminate\Http\JsonResponse
     * @response 200 {"code":200,"msg":"success","data":"退出登录"}
     */
    public function logout()
    {
        $user = Auth::guard('api')->user()->toArray();
        $user['last_login_time'] = date('Y-m-d H:i:s');
        $user['last_ip'] = getIp();
        User::where('id', $user['id'])->update($user);
        $this->guard()->logout();
        return response()->json(encodeMsg('退出成功', 200));
    }

    /**
     * Refresh a token.
     * 刷新token
     * @return \Illuminate\Http\JsonResponse
     * @response 200 {"code":200,"msg":"success","data":{"access_token":"xxx","access_type":"Bearer","expire":3600}}
     */
    public function refresh()
    {
        return $this->respondWithToken($this->guard()->refresh());
    }

    /**
     * Get the token array structure.
     *
     * @param string $token
     *
     * @return \Illuminate\Http\JsonResponse
     */
    protected function respondWithToken($token)
    {
        return response()->json(encodeMsg([
            'access_token' => $token,
            'token_type' => 'Bearer',
            'expires_in' => $this->guard()->factory()->getTTL() * 10
        ], 200));
    }

    /**
     * Get the guard to be used during authentication.
     *
     * @return \Illuminate\Contracts\Auth\Guard
     */
    public function guard()
    {
        return Auth::guard('api');
    }

    /**
     * @param $request
     * @return Error
     * 验证登录账号和密码
     * account 用户账号
     * password 用户密码
     * code 验证码
     */
    public function checkPost($request)
    {
        $name = $request->input('username');
        $pwd = $request->input('password');
        $code = $request->input('code');
        $key = $request->input('key');
//        if (is_null($code)) {
//            return response()->json(encodeMsg("请输入验证码", 400));
//        }
        if (is_null($name) || is_null($pwd)) {
            return response()->json(encodeMsg("请输入用户名或密码", 400));
        }
        $login = User::where(Fields::UNAME, $name)->first();
        $this->user = $login;
        if (!$login) {
            return response()->json(encodeMsg("用户名或密码错误", 400));
        }
        $hash = Hash::check($pwd, $login->password);
        if (!$hash) {
            return response()->json(encodeMsg("用户名或密码错误", 400));
        }
        //测试使用--Y6AncRSKp3fsZINv
//        if ($code != 'Y6AncRSKp3fsZINv') {
//            if (!captcha_check($code, $key)) {
//                return response()->json(encodeMsg("验证码不正确", 400));
//            }
//        }

    }

    /**
     * 获取验证码
     * @response
     */
    public function getCode()
    {
        $data = app('captcha')->create('flat', true);
        return response()->json(encodeMsg($data, 200));
    }

    //生成二维码
    public function qrcode()
    {
        $param = generateToken(40);
        Redis::setex('key', 300, $param);
        $qrcode = "data:image/png;base64,".base64_encode(QrCode::format('png')->size(400)->generate('http://www.baidu.com/'.$param));//网址为手机端授权登录页面地址
        // dd(Redis::get('key'));
        $data['code'] = $param;
        $data['qrcode'] = $qrcode;
        return response()->json(encodeMsg($data, 200));
    }

    /**
     * 二维码回传信息-手机端
     * @param Request $request
     * @bodyParam id int required 用户id
     * @bodyParam username string required 登录名
     * @bodyParam password string required 登陆密码
     * @bodyParam code string required 二维码包含信息
     * @return \Illuminate\Http\JsonResponse
     *
     */
    public function getQrInfo(Request $request)
    {
        $code = $request->input('code','');
        $param = Redis::get('key');
        if ($code != $param) {
            return response()->json(encodeMsg('二维码已过期',400));
        }
        $id = $request->input('id','');
        if (empty($id)) {
            return response()->json(encodeMsg('没有用户登录信息',404));
        }
        $info = [
            'id' => $id,
            'username' => $request->input('username',''),
            'password' => $request->input('password','')
        ];
        if ($info == []) {
            return response()->json(encodeMsg('用户不存在!',404));
        } else {
            $info = json_encode($info);
            Redis::setex('info',1800,$info);
            return response()->json(encodeMsg('登录成功!',200));
        }
    }

    /**
     * 二维码登录-pc端
     * @param Request $request
     * @bodyParam code string required 二维码包含信息
     * @return \Illuminate\Http\JsonResponse
     *
     */
    public function qrLogin(Request $request)
    {
        $code = $request->input('code','');
        $param = Redis::get('key');
        if ($code != $param) {
            return response()->json(encodeMsg('二维码已过期',400));
        }
        $info = json_decode(Redis::get('info'),true);
        $info = User::where($info)->first();
        if ($info == []) {
            return response()->json(encodeMsg('用户未登录',404));
        } else {
            $token = $this->guard()->login($info);
            if ($token) {
                return $this->respondWithToken($token);
            }
        }
    }

}
